import base64
import random
import time
import certifi
import urllib3
import automatic.protobuf.yang_pb2 as yang
from automatic.web.RequestHelper import RequestHelper


class DataPoster(object):
    def __init__(self, user_token, map_type):
        self._user_token = user_token
        self._map_type = map_type

    def send_solution(self, solution_dict, random_seed: str):
        upload_data_link = self._get_upload_data_link()
        request_data = self._generate_request_data(solution_dict, random_seed)
        request_header = RequestHelper().generate_request_header(self._user_token)
        self._make_request(upload_data_link, request_data, request_header)

    def _make_request(self, request_link, request_data, request_header):
        pool_manager = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where(), timeout=30)
        print("提交结果前请耐心等待{}秒".format(request_data["rank_time"]))
        time.sleep(request_data["rank_time"])
        response = pool_manager.request("POST", request_link, fields=request_data, headers=request_header)
        print("服务器返回结果为: {}".format(response.data.decode()))
        response.close()

    def _get_upload_data_link(self):
        if self._map_type == "normal":
            return "https://cat-match.easygame2021.com/sheep/v1/game/game_over_ex"
        elif self._map_type == "topic":
            return "https://cat-match.easygame2021.com/sheep/v1/game/topic/game_over"
        else:
            return None

    def _generate_request_data(self, solution_dict, random_seed):
        pass_time = random.randint(60, 150)
        if self._map_type == "normal":
            play_info = self._generate_encry_data(solution_dict, 3)
            return self._generate_normal_request_data(random_seed, pass_time, play_info)
        elif self._map_type == "topic":
            play_info = self._generate_encry_data(solution_dict, 4)
            return self._generate_topic_request_data(random_seed, pass_time, play_info)
        else:
            return None

    @staticmethod
    def _generate_encry_data(protobuf_list, game_type):
        match_play_info = yang.MatchPlayInfo()
        match_play_info.gameType = game_type
        step_info_list = yang.StepInfoList()
        for card_index, card_type in protobuf_list.items():
            step_info_list.chessIndex = int(card_index)
            step_info_list.timeTag = card_type
            match_play_info.stepInfoList.append(step_info_list)
        out_b = match_play_info.SerializeToString()
        return base64.b64encode(out_b).decode()

    def _generate_normal_request_data(self, random_seed, pass_time, play_info):
        result_dict = self._generate_data_template(random_seed, pass_time)
        result_dict.update({"rank_role": 1, "rank_score": 1, "skin": 1})
        result_dict["MatchPlayInfo"] = play_info
        return result_dict

    def _generate_topic_request_data(self, random_seed, pass_time, play_info):
        result_dict = self._generate_data_template(random_seed, pass_time)
        result_dict["play_info"] = play_info
        return result_dict

    @staticmethod
    def _generate_data_template(random_seed, pass_time, pass_success=True):
        result_dict = dict()
        result_dict["rank_time"] = pass_time
        result_dict["MapSeed2"] = random_seed
        result_dict["rank_state"] = 1 if pass_success else 2
        result_dict["Version"] = "0.0.1"
        return result_dict
